package com.example.springboot2022nocv.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.springboot2022nocv.entity.NocvData;
import com.example.springboot2022nocv.service.IndexService;
import com.example.springboot2022nocv.vo.DataView;
import com.example.springboot2022nocv.vo.NocvDataVo;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * @author 程序员小洋
 * @version 2022.3
 * @date 2022/12/23 20:06
 * @title
 */
@SuppressWarnings("all")
@RestController
public class ChinaDataAdminController {

    @Autowired
    private IndexService indexService;

    /**
     * 分页查询
     *
     * @return
     */
    @GetMapping("/listDataByPage")
    public DataView listDataByPage(NocvDataVo nocvDataVo) {

        // 1.创建分页的对象 当前页 每页限制大小
        IPage<NocvData> page = new Page<>(nocvDataVo.getPage(), nocvDataVo.getLimit());

        // 2.创建模糊查询条件
        QueryWrapper<NocvData> queryWrapper = new QueryWrapper<>();
        queryWrapper.like(!(nocvDataVo.getName() == null), "name", nocvDataVo.getName());

        // 3.疫情数据确诊最多的排在最上面
        queryWrapper.orderByDesc("value");

        // 4.查询数据库
        indexService.page(page, queryWrapper);

        // 5.返回数据封装
        DataView dataView = new DataView(page.getTotal(), page.getRecords());

        return dataView;
    }


    /**
     * 根据id删除数据
     *
     * @param id
     * @return
     */
    @RequestMapping("/china/deleteById")
    public DataView deleteById(Integer id) {
        indexService.removeById(id);
        DataView dataView = new DataView();
        dataView.setCode(200);
        dataView.setMsg("删除中国地图数据成功!");
        return dataView;
    }

    /**
     * 新增或者修改[id]
     * id: nocvData 有值修改 没有值就是新增
     * update nocv_data set name = "  where id = ?
     * insert into
     *
     * @param nocvData
     * @return
     */
    @PostMapping("/china/addOrUpdateChina")
    public DataView addOrUpdateChina(NocvData nocvData) {
        boolean save = indexService.saveOrUpdate(nocvData);
        DataView dataView = new DataView();
        if (save) {
            dataView.setCode(200);
            dataView.setMsg("新增中国地图数据成功!");
            return dataView;
        }
        dataView.setCode(100);
        dataView.setMsg("新增中国地图数据失败!");
        return dataView;
    }

    /**
     * Excel的拖拽或者点击上传
     * 1.前台页面发送一个请求 上传 MultipartFile
     * 2.controller 上传 MultipartFile 参数
     * 3.POI 解析文件 里面的数据一行一行全部解析出来
     * 4.每一条数据插入数据库
     * 5.mybatiplus 批量saveBatch(list)
     */

    @PostMapping("/excelImportChina")
    public DataView uploadExcel(@RequestParam("file") MultipartFile file) {

        DataView dataView = new DataView();

        // 1.文件不能为空
        if (file.isEmpty()) {
            dataView.setMsg("文件为空 不能上传!");
        }

        try {
            // 2.POI获取Excel解析数据
            HSSFWorkbook wb = new HSSFWorkbook(file.getInputStream());
            HSSFSheet sheet = wb.getSheetAt(0);

            // 3.定义一个程序集合 接收文件中的数据
            List<NocvData> list = new ArrayList<>();
            HSSFRow row = null;

            // 4.解析数据 装到集合里面
            for (int i = 0; i < sheet.getPhysicalNumberOfRows(); i++) {
                // 4.1 定义实体
                NocvData nocvData = new NocvData();
                // 4.2 获取每一行数据
                row = sheet.getRow(i);
                // 4.3 解析数据
                nocvData.setName(row.getCell(0).getStringCellValue());
                nocvData.setValue(((int) row.getCell(1).getNumericCellValue()));
                // 5.添加list集合
                list.add(nocvData);
            }
            // 6.插入数据库
            //循环展示导入的数据，实际应用中应该校验并存入数据库
            indexService.saveBatch(list);
            dataView.setCode(200);
            dataView.setMsg("小可爱,excel已经被你插入成功了!");
            return dataView;
        } catch (Exception e) {
            e.printStackTrace();
        }
        dataView.setCode(100);
        dataView.setMsg("导入失败");
        return dataView;
    }

    /**
     * 导出Excel数据 中国疫情数据
     * 1. 查询数据库
     * 2. 建立Excel对象 封装数据
     * 3. 建立输出流 输出文件
     */
    @RequestMapping("/excelOutportChina")
    public void exportOutportChina(HttpServletResponse response)  {

        // 1.查询数据库[查询所有,复核人条件的数据给你查询来]
        List<NocvData> list = indexService.list();

        // 2.建立Excel对象 封装数据
        response.setCharacterEncoding("utf-8");

        // 2.1 创建Excel对象
        HSSFWorkbook wb = new HSSFWorkbook();
        // 2.2 创建sheet对象
        HSSFSheet sheet = wb.createSheet("中国疫情数据sheet1");

        // 2.3 创建表头
        HSSFRow hssfRow = sheet.createRow(0);
        hssfRow.createCell(0).setCellValue("城市名称");
        hssfRow.createCell(1).setCellValue("确诊数量");

        // 3.遍历数据 封装Excel工作对象
        for (NocvData data : list) {
            HSSFRow dataRow = sheet.createRow(sheet.getLastRowNum()+1);
            dataRow.createCell(0).setCellValue(data.getName());
            dataRow.createCell(1).setCellValue(data.getValue());
        }

        // 4.建立输出流 输出浏览器文件
        OutputStream os = null ;

        try {
            // 4.1 设置一下Excel名字 输出类型 编码
            response.setContentType("application/octet-stream;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + new String("中国疫情数据表".getBytes(),"iso-8859-1") + ".xls");

            // 4.2输出文件
            os = response.getOutputStream();
            wb.write(os);
            os.flush();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }finally {
            // 5.关闭输出流
            if (os != null){
                try {
                    os.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
